package cn.itcast.nems.manager.util;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Objects;

public class Md5Util {
    private final  static  Logger log = LoggerFactory.getLogger(Md5Util.class) ;
    /**
     * 通过参数 生成 签名(md5)信息 并追加到参数列表返回
     * 参数顺序 以入参的 map key 顺序为主（建议 传递 linkedMap）
     * 现有业务 参数顺序都以 ascii排序
     *
     * @param param
     * @param appKey:秘钥
     */
    public static void handlerSigUrlByMd5(Map<String, String> param, String appKey) {

        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : param.entrySet()) {
            if(Objects.nonNull(entry.getValue())){
                stringBuilder.append(entry.getKey());
                stringBuilder.append("=");
                stringBuilder.append(entry.getValue());
                stringBuilder.append("&");
            }
        }
        stringBuilder.append(appKey);
        String md5Str = stringBuilder.toString();
        log.info("请求参数: {}, 生成签名: {}" , JSON.toJSONString(param) , md5Str);
        String sign = encryption(md5Str).toLowerCase();
        param.put("sig", sign);
    }

    public static void handlerSignature(Map<String, Object> param, String appKey) {
        String sign = calSignature(param, appKey);
        param.put("sig", sign);
    }

    public static String calSignature(Map<String, Object> param, String appKey) {
        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, Object> entry : param.entrySet()) {
            if(Objects.nonNull(entry.getValue())){
                stringBuilder.append(entry.getKey());
                stringBuilder.append("=");
                stringBuilder.append(entry.getValue());
                stringBuilder.append("&");
            }
        }
        stringBuilder.append(appKey);
        String md5Str = stringBuilder.toString();
        log.info("请求参数: {}, 生成签名: {}" , JSON.toJSONString(param) , md5Str);
        return encryption(md5Str).toLowerCase();
    }

    public static String encryption(String plain) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(
                    plain.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Huh, MD5 should be supported?", e);
        }

        return hexString(hash);
    }

    public static final String hexString(byte[] bytes) {
        StringBuilder buffer = new StringBuilder();
        for (byte aByte : bytes) {
            buffer.append(hexString(aByte));
        }
        return buffer.toString();
    }

    public static String hexString(byte byte0) {
        char[] ac = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                'B', 'C', 'D', 'E', 'F' };
        char[] ac1 = new char[2];
        ac1[0] = ac[byte0 >>> 4 & 0xf];
        ac1[1] = ac[byte0 & 0xf];
        return new String(ac1);
    }

    /**
     * 生成一个16位数的字符，用于url定位
     * @return 加密字符
     */
    public static String createUrl(){
        String encryption = encryption(String.valueOf(System.currentTimeMillis()));
        return encryption.substring(0, 15).toLowerCase();
    }
}
